<?php

namespace App\Utils\Service;

use Illuminate\Support\Facades\Redis;

/**
 * 漏桶速度限制后注册服务类
 * gao
 */
class LeakyBucketRateLimiter
{
    private $bucketSize;
    private $leakRate;

    public function __construct($bucketSize, $leakRate)
    {
        $this->bucketSize = $bucketSize;
        $this->leakRate = $leakRate;
    }

    //检查是否允许请求过来
    public function check($id, $tokens)
    {
        $tokens = intval($tokens);

        $currentTokens = Redis::hget('rate_limit', $id);
        if ($currentTokens === false) {
            $currentTokens = $this->bucketSize;
        } else {
            $currentTokens= $currentTokens - floor((microtime(true)-$currentTokens)*$this->leakRate);
            if ($currentTokens<0) {
                $currentTokens =0;
            }
            $currentTokens = min($this->bucketSize, $currentTokens + $tokens);
        }

        Redis::hset('rate_limit', $id, microtime(true));
        Redis::expire('rate_limit', 3600);

        return $currentTokens >= $tokens;
    }

}
